#ifndef API_SERVER_H
#define API_SERVER_H

#include <functional>
#include <string>
#include <vector>

#include "common/elements/element.h"
#include "common/elements/element_type.hpp"

#include "common/api/changes.h"
#include "common/api/result.hpp"

namespace Api
{

struct Server final
{
    // -- GetIds -- //
    typedef std::function<
        std::vector<unsigned>(
            const Uuids::Uuid& sessionUuid,
            Elements::ElementType type,
            const std::string& filter
        )>
        GetIdsFunction;
    static std::string getIdsCall(
        const std::string& requestBody,
        const GetIdsFunction& function
    );

    // -- GetElements -- //
    typedef std::function<
        std::vector<std::shared_ptr<Elements::Element>>(
            const Uuids::Uuid& sessionUuid,
            Elements::ElementType type,
            const std::vector<unsigned>& ids
        )>
        GetElementsFunction;
    static std::string getElementsCall(
        const std::string& requestBody,
        const GetElementsFunction& function
    );

    // -- AddElement -- //
    typedef std::function<
        unsigned(
            const Uuids::Uuid& sessionUuid,
            std::shared_ptr<Elements::Element> element
        )>
        AddElementFunction;
    static std::string addElementCall(
        const std::string& requestBody,
        const AddElementFunction& function
    );

    // -- SetElement -- //
    typedef std::function<
        bool(
            const Uuids::Uuid& sessionUuid,
            std::shared_ptr<Elements::Element> element
        )>
        SetElementFunction;
    static std::string setElementCall(
        const std::string& requestBody,
        const SetElementFunction& function
    );

    // -- DelElement -- //
    typedef std::function<
        bool(
            const Uuids::Uuid& sessionUuid,
            Elements::ElementType type,
            unsigned id
        )>
        DelElementFunction;
    static std::string delElementCall(
        const std::string& requestBody,
        const DelElementFunction& function
    );

    // -- HasChanges -- //
    typedef std::function<
        Changes(
            const Uuids::Uuid& sessionUuid
        )>
        HasChangedFunction;
    static std::string hasChangesCall(
        const std::string& requestBody,
        const HasChangedFunction& function
    );

    // -- Login -- //
    typedef std::function<
        AuthResult(
            const std::string& userLogin,
            const std::string& password
        )>
        LoginFunction;
    static std::string loginCall(
        const std::string& requestBody,
        const LoginFunction& function
    );

    // -- Logout -- //
    typedef std::function<
        bool(
            const Uuids::Uuid& sessionUuid,
            const std::string& userLogin
        )>
        LogoutFunction;
    static std::string logoutCall(
        const std::string& requestBody,
        const LogoutFunction& function
    );
};

} // namespace Api

#endif // API_SERVER_H
